﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace psafth.FSR.Lapcounter.UserControls
{
    public partial class ManageDriversUC : UserControl
    {
        Driver SelectedDriver;

        DbEntities db;
        public ManageDriversUC()
        {
            InitializeComponent();

            this.BackColor = Color.Transparent;

            db = new DbEntities();

            UpdateDriverGrid();

        }

        private void UpdateDriverGrid()
        {
            DataGridViewDrivers.Rows.Clear();

            foreach (Driver d in db.Drivers)
            {
                DataGridViewDrivers.Rows.Add(d.LicenceNumber, d.FirstName, d.LastName);
            }

            DataGridViewDrivers.Update();
            DataGridViewDrivers.Sort(DataGridViewDrivers.Columns["Firstname"], ListSortDirection.Ascending);
        }

        private void btn_save_Click(object sender, EventArgs e)
        {

        }

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
        }

        private void dataGridView1_SelectionChanged(object sender, EventArgs e)
        {

            if (DataGridViewDrivers.SelectedRows.Count > 0)
            {

                int i = DataGridViewDrivers.SelectedRows[0].Index;

                string s = (string)DataGridViewDrivers.Rows[i].Cells["LicenceNumber"].Value;

                TransponderListBox.Items.Clear();

                SelectedDriver = GetDriver(s);

                if (SelectedDriver != null)
                {
                    FillTransponderListBox(SelectedDriver);
                }
            }
        }

        private void btn_AddTransponder_Click(object sender, EventArgs e)
        {
            AddTransponderValue value = AddTransponderForm.GetInput(this);

            if (value.Result == DialogResult.OK && !string.IsNullOrEmpty(value.TransponderId))
            {
                try
                {
                    // Validate transponderId.
                    foreach (Transponder t in db.Transponders)
                    {
                        if (t.TransponderId == int.Parse(value.TransponderId))
                        {
                            MessageBox.Show(string.Format("Transponder {0} tillhör redan {1} {2}", t.TransponderId, t.Owner.LicenceNumber, t.Owner.FirstName + " " + t.Owner.LastName), "Ett fel har inträffat", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return;
                        }
                    }

                    TransponderListBox.Items.Clear();

                    Driver driver = GetDriver(GetLicenceFromSelectedRow());

                    try
                    {

                        if (driver != null)
                        {
                            Transponder t = new Transponder();

                            t.OwnerLicenceNumber = driver.LicenceNumber;
                            t.TransponderId = int.Parse(value.TransponderId);

                            driver.Transponders.Add(t);
                            db.Transponders.Add(t);

                            db.SaveChanges();

                            FillTransponderListBox(driver);
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString(), "Ett fel har inträffat", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), "Ett fel har inträffat", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        /// <summary>
        /// Gets the licence number for the currently selected row in DataGridView
        /// </summary>
        /// <returns>Licence number as string.</returns>
        private string GetLicenceFromSelectedRow()
        {
            try
            {
                int i = DataGridViewDrivers.SelectedRows[0].Index;

                return (string)DataGridViewDrivers.Rows[i].Cells["LicenceNumber"].Value;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Ett fel har inträffat", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return null;
            }
        }

        /// <summary>
        /// Gets the driver-object from a given TransponderId. Returns the owner of the Transponder.
        /// </summary>
        /// <param name="TransponderId">TransponderId</param>
        /// <returns>Driver</returns>
        private Driver GetDriver(int TransponderId)
        {
            foreach (Transponder t in db.Transponders)
            {
                if (t.TransponderId == TransponderId)
                {
                    return t.Owner;
                }
            }

            return null;
        }


        /// <summary>
        /// Gets the driver-object from a given licence number
        /// </summary>
        /// <param name="LicenceNumber">LicenceNumber</param>
        /// <returns>Driver</returns>
        private Driver GetDriver(string LicenceNumber)
        {
            foreach (Driver d in db.Drivers)
            {
                if (d.LicenceNumber == LicenceNumber)
                {
                    return d;
                }
            }

            return null;
        }

        /// <summary>
        /// Gets the transponder-object from a given transponderId
        /// </summary>
        /// <param name="TransponderId">TransponderId</param>
        /// <returns>Transponder</returns>
        private Transponder GetTransponder(int TransponderId)
        {
            foreach (Transponder t in db.Transponders)
            {
                if (t.TransponderId == TransponderId)
                {
                    return t;
                }
            }

            return null;
        }

        private void btn_deleteTransponder_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Vill du ta bort transponder?", "Bekräfta borttagning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
            {
                try
                {
                    int tId = (int)TransponderListBox.SelectedItem;

                    Transponder ToDelete = GetTransponder(tId);

                    if (ToDelete != null)
                    {
                        db.Transponders.Remove(ToDelete);
                        db.SaveChanges();

                        Driver driver = GetDriver(GetLicenceFromSelectedRow());

                        FillTransponderListBox(driver);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), "Ett fel har inträffat", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void FillTransponderListBox(Driver d)
        {
            TransponderListBox.Items.Clear();

            if (d != null)
            {
                foreach (Transponder t in d.Transponders)
                    TransponderListBox.Items.Add(t.TransponderId);
            }
        }

        private void btn_AddDriver_Click(object sender, EventArgs e)
        {
            EditDriverValue value = EditDriverForm.GetInput(this, null);

            if (value.Result == DialogResult.OK && !string.IsNullOrEmpty(value.FirstName) && !string.IsNullOrEmpty(value.LastName) && !string.IsNullOrEmpty(value.LicenceNo))
            {
                try
                {
                    db.Drivers.Add(new Driver() { FirstName = value.FirstName, LastName = value.LastName, LicenceNumber = value.LicenceNo });

                    db.SaveChanges();

                    UpdateDriverGrid();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message + ex.InnerException.Message, "Ett fel har inträffat", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void btn_DeleteDriver_Click(object sender, EventArgs e)
        {
            if (SelectedDriver != null)
            {
                if (MessageBox.Show("Vill du ta bort föraren och dess transpondrar?", "Bekräfta borttagning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
                {
                    try
                    {
                        HeatDriver heatDriver = db.HeatDriverSet.FirstOrDefault(delegate(HeatDriver d){
                            return d.Driver.LicenceNumber == SelectedDriver.LicenceNumber;
                        });

                        if (heatDriver != null)
                        {
                            MessageBox.Show("Föraren är refererad i ett eller flera heat. Tas denna referens bort kan historik oförtydligas. Avbryter.", "Varning!", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1);
                        }
                        else
                        {
                            List<Transponder> transponders = new List<Transponder>(db.Drivers.Find(SelectedDriver.LicenceNumber).Transponders);

                            foreach (Transponder t in transponders)
                            {
                                db.Transponders.Remove(t);
                            }

                            db.SaveChanges();

                            db.Drivers.Remove(SelectedDriver);
                            db.SaveChanges();

                            UpdateDriverGrid();
                        }
                    }
                    catch (Exception ex)
                    {
                        db = new DbEntities();
                        MessageBox.Show("Det gick inte att ta bort föraren. \n" + ex.Message, "Ett fel inträffade", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                }
            }
        }

        private void btn_EditDriver_Click(object sender, EventArgs e)
        {
            if (SelectedDriver != null)
            {
                EditDriverValue value = EditDriverForm.GetInput(this, SelectedDriver);

                if (value.Result == DialogResult.OK)
                {
                    if(!string.IsNullOrEmpty(value.FirstName) && !string.IsNullOrEmpty(value.LastName) && !string.IsNullOrEmpty(value.LicenceNo)){
                        
                        Driver dr = db.Drivers.First(d => d.LicenceNumber == SelectedDriver.LicenceNumber);

                        if (dr != null)
                        {
                            dr.FirstName = value.FirstName;
                            dr.LastName = value.LastName;
                            
                            db.SaveChanges();

                            UpdateDriverGrid();
                        }
                        else
                        {
                            MessageBox.Show("Något gick snett..");
                        }
                    }
                    else{
                        MessageBox.Show("Alla fält måste fyllas i.");
                    }
                }
            }
        }
    }

    public class AddTransponderValue
    {
        public string TransponderId { get; set; }
        public DialogResult Result { get; set; }
    }

    public class EditDriverValue
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string LicenceNo { get; set; }

        public DialogResult Result { get; set; }
    }

    public class EditDriverForm : Form
    {
        private TextBox tbFirstnameBox;
        private TextBox tbLastnameBox;
        private TextBox tbLicenceBox;

        private Button btnSave;
        private Button btnCancel;

        private Label lblHeader;
        private Label lblFirstname;
        private Label lblLastname;
        private Label lblLicence;

        private bool fNameOK = false;
        private bool lNameOK = false;
        private bool licenceOK = false;

        private EditDriverForm(Driver driver)
        {
            this.Height = 220;
            this.Width = 220;

            this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;


            string headertxt = "Lägg till förare";
            if (driver != null)
                headertxt = "Redigera förare";

            lblHeader = new Label();
            lblHeader.Text = headertxt;

            lblFirstname = new Label();
            lblFirstname.Text = "Förnamn:";
            lblFirstname.Location = new Point(10, 20);
            lblFirstname.Width = 80;

            tbFirstnameBox = new TextBox();
            tbFirstnameBox.Location = new Point(90, 20);
            tbFirstnameBox.KeyUp += tbFirstnameBox_KeyUp;

            lblLastname = new Label();
            lblLastname.Text = "Efternamn:";
            lblLastname.Location = new Point(10, 45);
            lblLastname.Width = 80;

            lblLicence = new Label();
            lblLicence.Text = "Licens:";
            lblLicence.Location = new Point(10, 70);
            lblLicence.Width = 80;

            tbLastnameBox = new TextBox();
            tbLastnameBox.Location = new Point(90, 45);
            tbLastnameBox.KeyUp += tbLastnameBox_KeyUp;

            tbLicenceBox = new TextBox();
            tbLicenceBox.Location = new Point(90, 70);
            tbLicenceBox.KeyUp += tbLicenceBox_KeyUp;


            if (driver != null)
                tbLicenceBox.ReadOnly = true;

            btnSave = new Button();
            btnSave.Text = "Spara";
            btnSave.Location = new Point(10, 95);

            btnCancel = new Button();
            btnCancel.Text = "Avbryt";
            btnCancel.Location = new Point(90, 95);

            btnSave.DialogResult = DialogResult.OK;
            btnCancel.DialogResult = DialogResult.Cancel;

            if (driver != null)
            {
                tbFirstnameBox.Text = driver.FirstName;
                tbLastnameBox.Text = driver.LastName;
                tbLicenceBox.Text = driver.LicenceNumber;
                lNameOK = true;
                fNameOK = true;
                licenceOK = true;
                btnSave.Enabled = true;
            }

            Controls.Add(lblFirstname);
            Controls.Add(lblLastname);
            Controls.Add(lblLicence);

            Controls.Add(tbFirstnameBox);
            Controls.Add(tbLastnameBox);
            Controls.Add(tbLicenceBox);
            Controls.Add(btnSave);
            Controls.Add(btnCancel);

            ValidateBoxes();
        }

        void tbLastnameBox_KeyUp(object sender, KeyEventArgs e)
        {
            lNameOK = false;

            if (!string.IsNullOrEmpty(tbLastnameBox.Text.Trim()))
                lNameOK = true;

            ValidateBoxes();
        }

        void tbFirstnameBox_KeyUp(object sender, KeyEventArgs e)
        {
            fNameOK = false;

            if (!string.IsNullOrEmpty(tbFirstnameBox.Text.Trim()))
                fNameOK = true;

            ValidateBoxes();
        }

        void tbLicenceBox_KeyUp(object sender, KeyEventArgs e)
        {
            licenceOK = false;

            if (!string.IsNullOrEmpty(tbLicenceBox.Text.Trim()))
                licenceOK = true;

            ValidateBoxes();
        }

        private void ValidateBoxes()
        {
            btnSave.Enabled = false;

            if (licenceOK && fNameOK && lNameOK)
                btnSave.Enabled = true;
        }

        public static EditDriverValue GetInput(IWin32Window owner, Driver d)
        {
            using (EditDriverForm values = new EditDriverForm(d))
            {
                DialogResult result = values.ShowDialog(owner);
                return new EditDriverValue()
                {
                    FirstName = values.tbFirstnameBox.Text,
                    LastName = values.tbLastnameBox.Text,
                    LicenceNo = values.tbLicenceBox.Text,
                    Result = result
                };
            }
        }
    }

    public class AddTransponderForm : Form
    {
        private TextBox tbInputBox;
        private Button btnOk;
        private Button btnCancel;
        private Label lblHeader;
        private Label lblDescription;

        private AddTransponderForm()
        {
            this.Height = 120;
            this.Width = 220;

            this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;

            lblHeader = new Label();
            lblHeader.Text = "Lägg till transponder";

            lblDescription = new Label();
            lblDescription.Text = "TransponderID:";
            lblDescription.Location = new Point(10, 20);
            lblDescription.Width = 80;

            tbInputBox = new TextBox();
            tbInputBox.Location = new Point(90, 18);
            tbInputBox.KeyDown += new KeyEventHandler(tbInputBox_KeyDown);

            btnOk = new Button();
            btnOk.Text = "Lägg till";
            btnOk.Location = new Point(10, 50);

            btnCancel = new Button();
            btnCancel.Text = "Avbryt";
            btnCancel.Location = new Point(90, 50);

            btnOk.DialogResult = DialogResult.OK;
            btnCancel.DialogResult = DialogResult.Cancel;

            Controls.Add(lblDescription);
            Controls.Add(tbInputBox);
            Controls.Add(btnOk);
            Controls.Add(btnCancel);
        }

        private void tbInputBox_KeyDown(object sender, KeyEventArgs e)
        {

            //Allow navigation keyboard arrows and numpad
            switch (e.KeyCode)
            {
                case Keys.Return:
                    btnOk.PerformClick();
                    break;

                case Keys.Up:
                case Keys.Down:
                case Keys.Left:
                case Keys.Right:
                case Keys.PageUp:
                case Keys.PageDown:
                case Keys.NumPad0:
                case Keys.NumPad1:
                case Keys.NumPad2:
                case Keys.NumPad3:
                case Keys.NumPad4:
                case Keys.NumPad5:
                case Keys.NumPad6:
                case Keys.NumPad7:
                case Keys.NumPad8:
                case Keys.NumPad9:
                    e.SuppressKeyPress = false;
                    return;
                default:
                    break;
            }

            //Block non-number characters
            char currentKey = (char)e.KeyCode;
            bool modifier = e.Control || e.Alt || e.Shift;
            bool nonNumber = char.IsLetter(currentKey) || char.IsSymbol(currentKey) || char.IsWhiteSpace(currentKey) || char.IsPunctuation(currentKey);

            if (!modifier && nonNumber)
                e.SuppressKeyPress = true;

            //Handle pasted Text
            if (e.Control && e.KeyCode == Keys.V)
            {
                //Preview paste data (removing non-number characters)
                string pasteText = Clipboard.GetText();
                string strippedText = "";
                for (int i = 0; i < pasteText.Length; i++)
                {
                    if (char.IsDigit(pasteText[i]))
                        strippedText += pasteText[i].ToString();
                }

                if (strippedText != pasteText)
                {
                    //There were non-numbers in the pasted text
                    e.SuppressKeyPress = true;

                    //OPTIONAL: Manually insert text stripped of non-numbers
                    TextBox me = (TextBox)sender;
                    int start = me.SelectionStart;
                    string newTxt = me.Text;
                    newTxt = newTxt.Remove(me.SelectionStart, me.SelectionLength); //remove highlighted text
                    newTxt = newTxt.Insert(me.SelectionStart, strippedText); //paste
                    me.Text = newTxt;
                    me.SelectionStart = start + strippedText.Length;

                }
                else
                    e.SuppressKeyPress = false;
            }
        }

        public static AddTransponderValue GetInput(IWin32Window owner)
        {
            using (AddTransponderForm values = new AddTransponderForm())
            {
                DialogResult result = values.ShowDialog(owner);
                return new AddTransponderValue
                {
                    TransponderId = values.tbInputBox.Text,
                    Result = result
                };
            }
        }
    }
}
